// 父类
class Person {
  String? name;
  int? age;
  double? _height;
  // 计算属性
  bool get isFree => (_height ??= 0) < 110;
  eat() => print('person eat');

  // 父类中如果有一个或多个自定义构造方法，子类必须至少实现其中的一个，不然会报错
  Person.init();
  Person(this.age);
}

// 抽象类
abstract class AbstractClass {
  // 这里 sum 没有实现，是一个抽象方法，抽象方法必须放到抽象类里面
  int sum(int a, int b);
}

mixin class MixinAClass {
  a() => print('a............');
  mixinTest() {
    print('mixinTest AClass');
  }

  eat() => print('minxIn a eat');
}

mixin class MixinBClass {
  b() => print('a............');
  eat() => print('minxIn b eat');
  mixinTest() {
    print('mixinTest BClass');
  }
}

// 拓展类
extension StudentExtension on Student {
  eat() => print('StudentExtension eat');
}

/*
书写顺序 extens在前，mixins在中间，implements最后
多个mixin
如果mixin存在冲突的部分，后面会覆盖前面的，没有冲突的则会保留，

问题:同名方法执行顺序
如果在这几种类扩展形式中,出现了同一名称的方法,执行优先级会是怎么样的呢? 总结如下.
执行优先级: 本类 > 混入mixins > 继承extends > 扩展extension
如果with后的多个类中有相同的方法，那么当调用该方法时，
会调用哪个类里的方法呢？
由于距离with关键字越远的类会重写前面类中的相同方法,结论如下所示.
    如果当前使用类重写了该方法，就会调用当前类中的方法。
    如果当前使用类没有重写了该方法，则会调用距离with关键字最远类中的方法。
 */
class Student extends Person
    with MixinAClass, MixinBClass
    implements AbstractClass {
  final String schoolName;

  study() => print('student study');

  // @override 表示复写父类的属性
  @override
  bool get isFree => (age ??= 0) < 18;

  // @override
  @override
  eat() => print('student eat');

  // 父类中如果有一个或多个自定义构造方法，子类必须至少实现其中的一个，不然会报错
  Student({this.schoolName = '北京'}) : super.init();

  @override
  int sum(int a, int b) {
    return a + b;
  }
}
